package model

import (
	"gin_vue_blog/utils/errmsg"
	"golang.org/x/crypto/bcrypt"
	"gorm.io/gorm"
	"log"
)

type User struct {
	gorm.Model
	Username string `gorm:"type:varchar(20)" json:"username" validate:"required,min=4,max=12" label:"用户名"`
	Password string `gorm:"type:varchar(100)" json:"password" validate:"required,min=6,max=20" label:"密码"`
	Role     int    `gorm:"type:int;default:2" json:"role" validate:"required,gte=2" label:"角色码"`
}

func CheckUserExist(username string) int {
	var user User
	db.Select("id").Where("username=?", username).First(&user)
	if user.ID > 0 {
		return errmsg.ERROR_USER_EXIST
	}
	return errmsg.ERROR_USER_NOT_EXIST
}

// 更新查询
func CheckUpUser(id int, name string) int {
	var user User
	db.Select("id").Where("username=?", name).First(&user)
	if user.ID == uint(id) {
		return errmsg.ERROR_USER_EXIST
	} else {
		return errmsg.SUCCESS
	}
}

// 添加用户
func AddUser(data *User) int {
	err := db.Create(&data).Error
	if err != nil {
		return errmsg.ERROR
	}
	return errmsg.SUCCESS
}

// 查询用户列表
func GetUserList(pageSize, pageNum int) ([]User, int) {
	var users []User
	switch {
	case pageSize >= 100:
		pageSize = 100
	case pageSize <= 0:
		pageSize = 10
	}

	if pageNum == 0 {
		pageNum = 1
	}
	err := db.Limit(pageSize).Offset((pageNum - 1) * pageSize).Find(&users).Error
	if err != nil {
		return nil, errmsg.ERROR
	}
	return users, errmsg.SUCCESS
}

// 修改密码
func ChangePassword(id int, data *User) int {
	var user User
	data.Password = ScriptPass(data.Password)
	err := db.Select("password").Where("id=?", id).First(&user).Updates(&data).Error
	if err != nil {
		return errmsg.ERROR
	}
	return errmsg.SUCCESS
}

// 密码加密与权限控制
func (u *User) BeforeCreate(_ *gorm.DB) error {
	u.Password = ScriptPass(u.Password)
	if u.Role != 1 {
		u.Role = 2
	}
	return nil
}

func ScriptPass(password string) string {
	const cost = 10
	hashPw, err := bcrypt.GenerateFromPassword([]byte(password), cost)
	if err != nil {
		log.Fatal(err)
	}
	return string(hashPw)
}

// 删除用户
func DeleteUser(id int) int {
	var user User
	err := db.Model(&user).Where("id=?", id).Delete(&user).Error
	if err != nil {
		return errmsg.ERROR
	}
	return errmsg.SUCCESS
}

// 编辑用户
func EditUser(id int, data *User) int {
	var user User
	maps := make(map[string]interface{})
	maps["username"] = data.Username
	maps["role"] = data.Role
	err := db.Model(&user).Where("id=?", id).Updates(maps).Error
	if err != nil {
		return errmsg.ERROR
	}
	return errmsg.SUCCESS
}

// 后台登录验证
func Login(username, password string) (User, int) {
	var user User
	var code int
	db.Where("username=?", username).First(&user)
	PasswordErr := bcrypt.CompareHashAndPassword([]byte(user.Password), []byte(password))
	if user.ID == 0 {
		code = errmsg.ERROR_USER_NOT_EXIST
	} else if PasswordErr != nil {
		code = errmsg.ERROR_PASSWORD_WORNG
	} else if user.Role != 1 {
		code = errmsg.ERROR_USER_NO_RIGHT
	} else {
		code = errmsg.SUCCESS
	}
	return user, code
}

// 前台登录验证
func LoginFront(username, password string) (User, int) {
	var user User
	var code int
	db.Where("username=?", username).First(&user)
	PasswordErr := bcrypt.CompareHashAndPassword([]byte(user.Password), []byte(password))
	if user.ID == 0 {
		code = errmsg.ERROR_USER_NOT_EXIST
	} else if PasswordErr != nil {
		code = errmsg.ERROR_PASSWORD_WORNG
	} else {
		code = errmsg.SUCCESS
	}
	return user, code
}
